package controllers;

import com.fasterxml.jackson.databind.JsonNode;
import com.google.gson.Gson;

import entities.Objects;
import entities.Station;
import entities.Tag;
import play.db.jpa.JPA;
import play.db.jpa.Transactional;
import play.libs.F;
import play.libs.Json;
import play.mvc.Controller;
import play.mvc.Result;

import javax.persistence.Query;

import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: eagami
 * Date: 03/05/14
 * Time: 16:00
 * To change this template use File | Settings | File Templates.
 */
public class ObjectsController extends Controller {

    @Transactional
    public static Result saveObject(){
        JsonNode json = request().body().asJson();
        Gson gson = new Gson();
        if(json.findValue("tag") != null && json.findValue("name") != null){
            Tag tag = gson.fromJson(!json.findValue("tag").isTextual() ? json.findValue("tag").toString() :
                    json.findValue("tag").asText(), Tag.class);
            tag = Tag.find.byId(tag.getId());
            Objects obj = new Objects();
            obj.setName(json.findValue("name").textValue());
            obj.setDescription(json.findValue("description") != null ? json.findValue("description").textValue() : null);
            obj.setObjectId(json.findValue("objectId") != null ? json.findValue("objectId").asInt() : null);
            obj.setId(json.findValue("id") != null ? json.findValue("objectId").asLong() : null);
            obj.setTag(tag);
            obj.save();
        }

        System.out.println(json);
        return ok();
    }

    @Transactional
    public static Result getAllObjects(){
        return ok(Json.toJson(ObjectsController.getAllRecentObjects()));
    }

    private static Map<Station,List<Objects>> getObjectInStationByDate(Date startDate, Date endDate,List<Long> stations){

        StringBuilder strQuery = new StringBuilder("select distinct o ,s ")
                                            .append("from History h ")
                                            .append("inner join h.object o ")
                                            .append("inner join h.station s ")
                                            .append("where h.startTime > ?1 ");

        if(stations != null && !stations.isEmpty()){
            strQuery.append(" and s.id in (?2)");
        }

        if(endDate != null){
            strQuery.append(" and h.lastUpdateTime < ?3 ");
        }

        Query query = JPA.em().createQuery(strQuery.toString());

        query.setParameter(1, startDate);

        if(stations != null && !stations.isEmpty()){
            query.setParameter(2, stations);
        }

        if(endDate != null){
            query.setParameter(3, endDate);
        }

        System.out.println(query.getResultList());

        Map mReturn = new HashMap<Station,Object>();

        List<Object[]> lstQuery= query.getResultList();

        for (Object[] objQuery : lstQuery) {
            Station sta = (Station) objQuery[1];

            if(!mReturn.containsKey(sta))
            {
                List<Objects> lObjects = new ArrayList<Objects>();

                lObjects.add((Objects)objQuery[0]);

                mReturn.put(sta, lObjects);
            }else{
                List<Objects> lst = (List<Objects>)mReturn.get(sta);
                lst.add((Objects)objQuery[0]);
            }
        }

        return mReturn;
    }

	public static Objects getObjectByTag(final Integer tagNumber) throws ClassCastException,Throwable {
		return JPA.withTransaction(new F.Function0<Objects>()  {
	        @Override
	        public Objects apply() throws ClassCastException,Throwable{
	        	int distatnce = 50;
	        	Station stations = null;
	        	StringBuilder strQuery = new StringBuilder("select distinct s ");
	    		   strQuery.append("from Objects s ");
	    		   strQuery.append("where s.id in (select max(o.id) ");
	    		   					strQuery.append("from Objects o ");
	    		   					strQuery.append("inner join o.tag t ");
	    		   					strQuery.append("where t.number = ?1) ");
	    					   
	    			Query query = JPA.em().createQuery(strQuery.toString());
	    			
	    			query.setParameter(1, tagNumber);
	    					
	    			List<Objects> lReturn = query.getResultList();
	    			if(lReturn.isEmpty())
	    				return null;
                return (Objects) lReturn.get(0);
             }
		});
	}
	
	@Transactional
	 public static List<Objects> getAllRecentObjects(){

	        StringBuilder strQuery = new StringBuilder("select distinct o ")
	                                            .append("from Objects o ")
	                                            .append("where o.id in (select max(os.id)  ")
	                                            				.append("from Objects os ")
	                                            				.append("group by os.tag )");
	       
	        Query query = JPA.em().createQuery(strQuery.toString());
	       
	        return query.getResultList();
	    }
}